home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 376-400 / 376 / plotter / src / diskussion.c < prev    next >
Text File  |  1995-03-14  |  11KB  |  456 lines

  1.  /********************************************************************/
  2.  /****                                                            ****/
  3.  /****                                                            ****/
  4.  /****    Program          : Diskussion.c                         ****/
  5.  /****                                                            ****/
  6.  /****    Version          :    03.71                             ****/
  7.  /****                                                            ****/
  8.  /****    Erstversion      : 04.11.1989                           ****/
  9.  /****                                                            ****/
  10.  /****    Letzte Änderung  : 05.08.1990                           ****/
  11.  /****                                                            ****/
  12.  /****    Compiliert mit   : siehe MAKEFILE                       ****/
  13.  /****                                                            ****/
  14.  /****    Gelinkt mit      : siehe MAKEFILE                       ****/
  15.  /****                                                            ****/
  16.  /********************************************************************/
  17.  /****                                                            ****/
  18.  /****                                                            ****/
  19.  /****               Copyright by Rüdiger Dreier                  ****/
  20.  /****                                                            ****/
  21.  /****                                                            ****/
  22.  /********************************************************************/
  23.  
  24.  #ifdef DEBUG
  25.  #include "Plotter.h"
  26.  #include <proto/tool.h>
  27.  #endif
  28.  #include <stdio.h>
  29.  #include <string.h>
  30.  #include "Plotter.h"
  31.  
  32.  #include <string.h>
  33.  #include <stdlib.h>
  34.  #define SCHRITTE 200
  35.  
  36.  DOUBLE BestF,BestX;
  37.  
  38.  char AusgabeString[125]; /* Höchster auftretender Wert : 123 */
  39.  #undef  GRENZE1
  40.  #define GRENZE1 0.0002
  41.  #define GRENZE2 0.0000002
  42.  #define NONULL  HUGE
  43.  
  44.  LONG ypos_Diskussion;
  45.  LONG xpos_Diskussion;
  46.  
  47.  VOID discuss(char *string,DOUBLE l,DOUBLE r,int modus,unsigned short sub)
  48.   {
  49.    double i,var,fl,fr,add,fwert,flp,frp,Zugabe,h,vzl,vzr;
  50.    char text[5];
  51.    char NoNull=0;
  52.    
  53.    StartBlock=Init_Mem(string); /* Struktur für die zu untersuchende Funktion */
  54.    if(!StartBlock)return;
  55.    MatheFehler=Init_Block(StartBlock);
  56.    MatheFehler|=PreCalc(StartBlock,Konstantenstart);
  57.    
  58.    switch(modus)
  59.     {
  60.      case 0:
  61.       {
  62.        Print(RastPort,DISK_NULLST,FARBE3,10,ypos_Diskussion);
  63.        break;
  64.       }
  65.      case 1:
  66.       {
  67.        Print(RastPort,DISK_EXTREMST,FARBE3,10,ypos_Diskussion);
  68.        break;
  69.       }
  70.      case 2:
  71.       {
  72.        Print(RastPort,DISK_WENDEST,FARBE3,10,ypos_Diskussion);
  73.        break;
  74.       }
  75.     };
  76.    add=Div(Sub(r,l),SCHRITTE);
  77.    l=Sub(l,add); /* Die Grenzen werden etwas erweitert, um Randextrema */
  78.    r=Add(r,add); /* zu erfassen                                        */
  79.    Zugabe=Div(add,SCHRITTE/2);
  80.    Calc_P(&fl,StartBlock,&l);
  81.    flp=Abs(fl);
  82.    
  83.    for(i=Add(l,add);Cmp(i,r)<=0;i=Add(i,add))
  84.     {
  85.      Calc_P(&fr,StartBlock,&i);
  86.      frp=Abs(fr);
  87.      if((Tst(fl)!=Tst(fr)) || (Cmp(frp,GRENZE1)==-1 && Tst(flp)))
  88.       {
  89.        /* Eine Nullstelle ! */
  90.        if(Tst(fl)!=Tst(fr))
  91.         {
  92.          var=Nullstelle(Sub(i,add),i);
  93.          i=Add(i,add);
  94.          Calc_P(&fr,StartBlock,&i);
  95.          frp=Abs(fr);
  96.         }
  97.        else
  98.         {
  99.          var=Nullstelle2(Sub(i,add),i);
  100.          if(Cmp(var,HUGE)==0)NoNull=1;
  101.          
  102.          if(Cmp(Add(var,Zugabe),i)>=1)
  103.           {
  104.            while(Cmp(frp,GRENZE1)==-1 && Cmp(i,r)==-1)
  105.             {
  106.              i=Add(i,add);
  107.              MatheFehler=Calc_P(&fr,StartBlock,&i);
  108.              frp=Abs(fr);
  109.             }
  110.           }
  111.         }
  112.        berechnen(&fwert,Formeln[sub],&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
  113.        
  114.        MatheFehler=Calc_P(&h,StartBlock,&var);
  115.        
  116.        if(MatheFehler!=0 || Cmp(Abs(h),GRENZE2)==1)
  117.         {
  118.          NoNull=1;
  119.         }
  120.        
  121.        if(modus>0)
  122.         {
  123.          h=Sub(var,GRENZE2);
  124.          Calc_P(&vzl,StartBlock,&h); /* f(x) links  neben Nullstelle */
  125.          h=Add(var,GRENZE2);
  126.          Calc_P(&vzr,StartBlock,&h); /* f(x) rechts neben Nullstelle */
  127.          if(Tst(vzl)==Tst(vzr))
  128.           {
  129.            NoNull=1;
  130.           }
  131.         }
  132.        
  133.        if(!NoNull)
  134.         {
  135.          switch(modus)
  136.           {
  137.            case 0:
  138.             {
  139.              /* f(x) */
  140.              text[0]=0;
  141.              /*strcpy(text,"");*/
  142.              break;
  143.             }
  144.            case 1:
  145.             {
  146.              /* f'(x) */
  147.              if(Cmp(fl,fr)==-1)
  148.               {
  149.                strcpy(text,"Min");
  150.               }
  151.              else
  152.               {
  153.                strcpy(text,"Max");
  154.               }
  155.              break;
  156.             }
  157.            case 2:
  158.             {
  159.              /* f''(x) */
  160.              if(Cmp(fl,fr)==-1)
  161.               {
  162.                strcpy(text,"R-L");
  163.               }
  164.              else
  165.               {
  166.                strcpy(text,"L-R");
  167.               }
  168.              break;
  169.             }
  170.           }
  171.          TextAusgabe(var,fwert,text);
  172.         }
  173.       }
  174.      NoNull=0;
  175.      fl=fr;
  176.      flp=frp;
  177.     }
  178.    Free_Block(StartBlock); /* Speicher freigeben */
  179.   }
  180.  
  181.  
  182.  /* Bestimmt Nullstelle, wenn Vorzeichenwechsel vorliegt */
  183.  DOUBLE Nullstelle(l,r)
  184.  double l,r;
  185.   {
  186.    double i,fl,fr,fm,nl,nr;
  187.    char tiefe=0;
  188.    
  189.    nl=l;
  190.    nr=r;
  191.    
  192.    if(tiefe==0)
  193.     {
  194.      BestF=100.0;
  195.      BestX=l;
  196.     }
  197.    
  198.    MatheFehler=Calc_P(&fl,StartBlock,&l);
  199.    if(MatheFehler==0&&Tst(fl)==0)return(l);
  200.    
  201.    MatheFehler=Calc_P(&fr,StartBlock,&r);
  202.    if(MatheFehler==0&&Tst(fr)==0)return(r);
  203.    /* Intervallschachtelung */
  204.    while(tiefe<=40)
  205.     {
  206.      i=Div(Add(nl,nr),2.000);
  207.      
  208.      MatheFehler=Calc_P(&fm,StartBlock,&i);
  209.      
  210.      if(MatheFehler==0)
  211.       {
  212.        if(Cmp(Abs(fm),4000.0)==1)
  213.         {
  214.          tiefe=42; /* Wird wohl keine Nullstelle sein */
  215.         }
  216.        if(Cmp(Abs(fm),BestF)==-1L)
  217.         {
  218.          BestF=Abs(fm); /* Besser als bisheriger Wert */
  219.          BestX=i;
  220.         }
  221.       }
  222.      
  223.      if(Tst(fl)!=Tst(fm))
  224.       {
  225.        nr=i;
  226.       }
  227.      else
  228.       {
  229.        nl=i;
  230.       }
  231.      tiefe++;
  232.     }
  233.    
  234.    if(MatheFehler!=0 && tiefe==41)
  235.     {
  236. /* Ist die Funktion nur für einen Randwert des ursprünglichen Bereichs l-r */
  237. /* definiert (z.B. sqr mit l=-0.5 und r=0.0), dann wird immer ein Fehler   */
  238. /* beim Berechnen des Funktionswertes für die Mitte festgestellt.          */
  239.      
  240.      MatheFehler=Calc_P(&fm,StartBlock,&r);
  241.      if(MatheFehler==0&&Cmp(Abs(fm),GRENZE2)==-1L)
  242.       {
  243.        i=r; /* Eine Näherung */
  244.       }
  245.      else
  246.       {
  247.        MatheFehler=Calc_P(&fm,StartBlock,&l);
  248.        if(MatheFehler==0 && Cmp(Abs(fm),GRENZE2)==-1L)
  249.         {
  250.          i=l; /* Eine Näherung */
  251.         }
  252.       }
  253.     }
  254.    
  255.    if(Cmp(Abs(fm),BestF)==1)i=BestX;
  256.    return(i);
  257.   }
  258.  
  259.  /* Bestimmt Nullstelle, wenn kein VZ vorliegt */
  260.  DOUBLE Nullstelle2(l,r)
  261.  double l,r;
  262.   {
  263.    double i,fl,fr,fm,flp,frp,fmp,add;
  264.    add=(Sub(r,l));
  265.    
  266.    Calc_P(&fl,StartBlock,&l);
  267.    flp=Abs(fl);
  268.    Calc_P(&fr,StartBlock,&r);
  269.    frp=Abs(fr);
  270.    
  271.    /* Sorgt dafür, daß r außerhalb des Bereiches unter GRENZE1 liegt */
  272.    if(Cmp(frp,GRENZE1)==-1)     
  273.     {
  274.      /* rechte Stelle suchen, für die f(x)>GRENZE1 */
  275.      while(Cmp(frp,GRENZE1)==-1)
  276.       {
  277.        r=Add(r,add);
  278.        Calc_P(&fr,StartBlock,&r);
  279.        frp=Abs(fr);
  280.        if(Tst(fl)!=Tst(fr))
  281.         {
  282.          l=Nullstelle(l,r);
  283.          return(l);
  284.         }
  285.       }
  286.     }
  287.    add=Div(Sub(r,l),SCHRITTE);
  288.    i=Add(l,add);
  289.    Calc_P(&fm,StartBlock,&i);
  290.    fmp=Abs(fm);
  291.    /* Tastet sich von links heran, solange wie die F-Werte immer kleiner werden */
  292.    while(Cmp(flp,fmp)==1)
  293.     {
  294.      l=i;
  295.      flp=fmp;
  296.      i=Add(i,add);
  297.      Calc_P(&fm,StartBlock,&i);
  298.      fmp=Abs(fm);
  299.      if(Tst(fl)!=Tst(fr))
  300.       {
  301.        l=Nullstelle(l,r);
  302.        return(l);
  303.       }
  304.     }
  305.    
  306.    i=Sub(r,add);
  307.    Calc_P(&fm,StartBlock,&i);
  308.    fmp=Abs(fm);
  309.    /* Tastet sich entsprechend von rechts heran */
  310.    while(Cmp(frp,fmp)==1&&Cmp(r,l)==1)
  311.     {
  312.      r=i;
  313.      frp=fmp;
  314.      i=Sub(i,add);
  315.      Calc_P(&fm,StartBlock,&i);
  316.      fmp=Abs(fm);
  317.      if(Tst(fl)!=Tst(fr))
  318.       {
  319.        l=Nullstelle(l,r);
  320.        return(l);
  321.       }
  322.     }
  323.    
  324.    if(Cmp(Min(flp,frp),GRENZE2)==-1)
  325.     {
  326.      if(Cmp(flp,frp)==1)
  327.       {
  328.        return(r);
  329.       }
  330.      else
  331.       {
  332.        return(l);
  333.       }
  334.     }
  335.    else
  336.     {
  337.      return(NONULL);
  338.     }
  339.   }
  340.  
  341.  VOID TextAusgabe(DOUBLE x,DOUBLE y,char *string)
  342.   {
  343.    char ZwischenString[50];
  344.    char xc[10],yc[10];
  345.    LONG max_x=562;
  346.    SHORT *a;
  347.    if(Groesse)
  348.     {
  349.      max_x=994;
  350.     }
  351.    
  352.    /* Besser: min(abs(xmn,xmp)) nehmen */
  353.    if(Cmp(Abs(x),Div(xmp,1000.0))==-1)x=0.0000; /* Runden */
  354.    if(Cmp(Abs(y),Div(ymp,1000.0))==-1)y=0.0000;
  355.    
  356.    UmwFtoS(xc,&x,3);
  357.    Laenge(xc,9);
  358.    UmwFtoS(yc,&y,3);
  359.    Laenge(yc,9);
  360.    
  361.    /*strcpy(ZwischenString,"(");*/
  362.    a=(SHORT *)ZwischenString;
  363.    *a=0x2800;
  364.    
  365.    strcat(ZwischenString,xc);
  366.    strcat(ZwischenString,"/");
  367.    strcat(ZwischenString,yc);
  368.    strcat(ZwischenString,")");
  369.    strcat(ZwischenString,string);
  370.    if(xpos_Diskussion>=max_x)
  371.     {
  372.      xpos_Diskussion=146;
  373.      ypos_Diskussion+=10;
  374.     }
  375.    Print(RastPort,ZwischenString,FARBE3,xpos_Diskussion,ypos_Diskussion);
  376.    xpos_Diskussion+=216; /* 29*8 */
  377.   }
  378.  
  379.  VOID TextAusgabe2(char *string)
  380.   {
  381.    LONG SPos=0;
  382.    LONG Max_Zeichen=53;
  383.    
  384.    if(Groesse)
  385.     {
  386.      Max_Zeichen=107;
  387.     }
  388.    
  389.    do
  390.     {
  391.      mid(AusgabeString,string,SPos,Max_Zeichen);
  392.      SPos+=Max_Zeichen;
  393.      Print(RastPort,AusgabeString,FARBE3,146L,ypos_Diskussion);
  394.      ypos_Diskussion+=10;
  395.     }
  396.    while(AusgabeString[0]!=0);
  397.    ypos_Diskussion-=10;
  398.    xpos_Diskussion=146;
  399.   }
  400.  
  401.  /* Fügt VOR dem string so viele Leerzeichen ein, */
  402.  /* daß der String laenge lang wird               */
  403.  VOID __asm Laenge(register __a0 char *string,
  404.                    register __d0 int laenge)
  405.   {
  406.    SHORT a;
  407.    SHORT i;
  408.    char HILFE[18];
  409.    
  410.    a=laenge-(strlen(string));
  411.    
  412.    for(i=0;i<a;i++)
  413.     {
  414.      HILFE[i]=32;
  415.     }
  416.    HILFE[i]=0;
  417.    strcat(HILFE,string);
  418.    strcpy(string,HILFE);
  419.   }
  420.  
  421.  VOID __asm Full_Discussion(register __d0 USHORT sub)
  422.   {
  423.    Loeschen();
  424.    strcpy(Abgeleitet[0],DISK_FOR);
  425.    UmwFtoS(&Abgeleitet[0][strlen(Abgeleitet[0])],&xmn,3);
  426.    strcat(Abgeleitet[0],"|");
  427.    UmwFtoS(&Abgeleitet[0][strlen(Abgeleitet[0])],&xmp,3);
  428.    strcat(Abgeleitet[0],"]");
  429.    Print(RastPort,Abgeleitet[0],FARBE3,10L,15L);
  430.    ypos_Diskussion=35;
  431.    
  432.    /* Bilden der 1. Ableitung */
  433.    strcpy(Formeln[10],Formeln[sub]);
  434.    strcpy(Abgeleitet[0],Ableiten(Formeln[10]));
  435.    
  436.    /* Bilden der 2. Ableitung */
  437.    strcpy(Formeln[10],Abgeleitet[0]);
  438.    strcpy(Abgeleitet[1],Ableiten(Formeln[10]));
  439.    
  440.    KoordinatenKreuz_gezeichnet=FALSE;
  441.    
  442.    Print(RastPort,"f  (x)        =",FARBE3,10L,ypos_Diskussion);
  443.    TextAusgabe2(Formeln[sub]);
  444.    discuss(Formeln[sub],xmn,xmp,0,sub);
  445.    ypos_Diskussion+=15;
  446.    
  447.    Print(RastPort,"f' (x)        =",FARBE3,10L,ypos_Diskussion);
  448.    TextAusgabe2(Abgeleitet[0]);
  449.    discuss(Abgeleitet[0],xmn,xmp,1,sub);
  450.    ypos_Diskussion+=15;
  451.    
  452.    Print(RastPort,"f''(x)        =",FARBE3,10L,ypos_Diskussion);
  453.    TextAusgabe2(Abgeleitet[1]);
  454.    discuss(Abgeleitet[1],xmn,xmp,2,sub);
  455.   }
  456.